package com.stormragetech.arthas.process.factory;

import com.stormragetech.arthas.common.constant.Constant;
import com.stormragetech.arthas.common.exception.ArthasException;
import com.stormragetech.arthas.common.util.Assert;
import lombok.extern.log4j.Log4j2;

import java.util.Map;

/**
 * description: action wrapper factory
 *
 * @author: Xue Bin
 * @version: 1.0.0-SNAPSHOT
 */
@Log4j2
public class AwareActionFactory implements ActionFactory {

    private Map<String, ActionWrapper<?>> actions;

    public AwareActionFactory(Map<String, ActionWrapper<?>> actions) {
        Assert.notNull(actions, "Map cannot be null !!!");
        this.actions = actions;
    }

    @Override
    public ActionWrapper<?> getWrapper(String path) throws ArthasException {
        for (String key : actions.keySet()) {
            if (path.contains(key)) {
                return actions.get(key);
            }
        }
        throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
    }

    @Override
    public Object getAction(String name) throws ArthasException {
        if (containsAction(name)) {
            return actions.get(name).getAction();
        } else {
            throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
        }
    }

    @Override
    public <T> T getAction(String name, Class<T> clazz) throws ArthasException {
        if (containsAction(name)) {
            ActionWrapper<T> wrapper = (ActionWrapper<T>) actions.get(name);
            if (clazz.getName().equals(wrapper.getName())) {
                return wrapper.getAction();
            } else {
                throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
            }
        } else {
            throw new ArthasException(Constant.PROC_ERR_CODE, Constant.PROC_NO_WRAP, ArthasException.APP_ERR);
        }
    }

    @Override
    public boolean containsAction(String name) {
        return null != actions && actions.keySet().stream().filter(key -> key.equals(name)).count() > 0;
    }

    @Override
    public String toString() {
        return "AwareActionFactory{" +
                "actions=" + actions +
                '}';
    }
}
